﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BusinessModel;
using EntityDataModel;
using System.ComponentModel;
using Controller.DataProvider;
using System.Data;
//////////////////////////////////
using BaseUtilities;
using ManageStore.IViews;
using System.Collections.ObjectModel;

namespace Controller
{
    public class ProductCtr : BaseCtr, IDataErrorInfo
    {
        public ProductCtr(IProductView pIProductView)
        {
            this.IProductView = pIProductView;
        }

        #region Properties
        // IProductView.
        public IProductView IProductView { get; set; }
        // ProductPro.
        private ProductPro _ProductPro;
        public ProductPro ProductPro
        {
            get
            {
                if (_ProductPro == null)
                {
                    _ProductPro = new ProductPro();
                }
                return _ProductPro;
            }
            set { _ProductPro = value; }
        }
        // ProductTypePro.
        private ProductTypePro _ProductTypePro;
        public ProductTypePro ProductTypePro
        {
            get
            {
                if (_ProductTypePro == null)
                {
                    _ProductTypePro = new ProductTypePro();
                }
                return _ProductTypePro;
            }
            set { _ProductTypePro = value; }
        }
        // EntityKey.
        private EntityKey _EntityKey;
        public EntityKey EntityKey
        {
            get
            {
                if (_EntityKey == null)
                {
                    _EntityKey = new EntityKey(BaseProvider.QualifyName + "." + ProductPro.EntityName, "Id", 0);
                }
                return _EntityKey;
            }
            set { _EntityKey = value; }
        }
        // Product.
        private Product _Product;
        public Product Product
        {
            get
            {
                if (_Product == null)
                    _Product = new Product();
                return _Product;
            }
            set { _Product = value; OnPropertyChanged("Product"); }
        }
        // LstErrorFields
        private Dictionary<string, string> _DicError;
        public Dictionary<string, string> DicError
        {
            get
            {
                if (_DicError == null)
                    _DicError = new Dictionary<string, string>();
                return _DicError;
            }
            set
            {
                _DicError = value;
            }
        }
        #endregion Properties

        #region Binding properties
        // Id
        public int Id
        {
            get
            {
                return Product.Id;
            }
            set
            {
                if (Product.Id != value)
                {
                    Product.Id = value;
                }
            }
        }
        // ProductTypeId
        public int? ProductTypeId
        {
            get
            {
                return Product.TypeId;
            }
            set
            {
                if (value.HasValue && Product.TypeId != value)
                {
                    Product.TypeId = value.Value;
                    OnPropertyChanged("ProductTypeId");
                }
            }
        }
        // ProductName
        public string ProductName
        {
            get
            {
                return Product.Name;
            }
            set
            {
                if (Product.Name != value)
                {
                    Product.Name = value;
                    OnPropertyChanged("ProductName");
                }
            }
        }
        // ProductCode
        public string ProductCode
        {
            get
            {
                return Product.Code;
            }
            set
            {
                if (Product.Code != value)
                {
                    Product.Code = value;
                    OnPropertyChanged("ProductCode");
                }
            }
        }
        //UnitId.
        public int UnitId
        {
            get { return Product.UnitId; }
            set
            {
                if (Product.UnitId != value)
                {
                    Product.UnitId = value;
                    OnPropertyChanged("UnitId");
                }
            }
        }
        // Note
        public string Note
        {
            get
            {
                return Product.Note;
            }
            set
            {
                if (Product.Note != value)
                {
                    Product.Note = value;
                    OnPropertyChanged("Note");
                }
            }
        }
        // LstProduct.
        private IList<Product> _LstProduct;
        public IList<Product> LstProduct
        {
            get
            {
                return _LstProduct;
            }
            set
            {
                if (_LstProduct != value)
                {
                    _LstProduct = value;
                }
            }
        }
        // LstProductType.
        private IList<ProductType> _LstProductType;
        public IList<ProductType> LstProductType
        {
            get
            {
                if(_LstProductType == null)
                    _LstProductType = ProductTypePro.GetAllLeafs().ToResult<IList<ProductType>>();
                return _LstProductType;
            }
        }
        // LstUnit.
        private IList<IdNameModel> _LstUnit;
        public IList<IdNameModel> LstUnit
        {
            get
            {
                if (_LstUnit == null)
                    _LstUnit = (new UnitPro()).GetIdNameAll().ToResult<IList<IdNameModel>>();
                return _LstUnit;
            }
        }
        #endregion Binding properties

        #region Private Method
        //----------------------------------------
        private void LoadListProduct()
        {
            LstProduct = new ObservableCollection<BusinessModel.Product>(MtdGetAll().ToResult<IList<Product>>());
        }
        //----------------------------------------
        private ResultModel MtdGetById(int pProductId)
        {
            EntityKey oEntityKey = new EntityKey(BaseProvider.QualifyName + "." + ProductPro.EntityName, "Id", pProductId);
            return ProductPro.GetById(oEntityKey);
        }
        //----------------------------------------
        private ResultModel MtdGetAll()
        {
            return ProductPro.GetAll();
        }
        #endregion Private Method

        #region Public View Handlers
        //----------------------------------------
        public bool MtdNew(params object[] pParams)
        {
            bool result = false;
            if (IProductView.BeforeHandler("EvtNew"))
            {
                LoadListProduct();
                IProductView.ReloadData();
                Product = new Product();
                DicError.Clear();
                IProductView.CompletedHandler("EvtNew");
            }
            return result;
        }
        //----------------------------------------
        public bool MtdEdit(params object[] pParams)
        {
            bool result = false;
            if (IProductView.BeforeHandler("EvtEdit"))
            {
                if (pParams.Count() == 1)
                {
                    Product = pParams[0] as Product;
                    if (Product == null)
                    {
                        IProductView.ErrorHandler("EvtEdit");
                    }
                    else
                    {
                        DicError.Clear();
                        IProductView.CompletedHandler("EvtEdit");
                    }
                }
            }
            return result;
        }
        //----------------------------------------
        public bool MtdDelete(params object[] pParams)
        {
            bool result = false;
            if (IProductView.BeforeHandler("EvtDelete"))
            {
                EntityKey oEntityKey = new EntityKey(BaseProvider.QualifyName + "." + ProductPro.EntityName, "Id", Product.Id);
                ResultModel oResultModel = ProductPro.DeleteById(oEntityKey);
                if (oResultModel.HasError)
                {
                    IProductView.ErrorHandler("EvtDelete", oResultModel);
                }
                else
                {
                    LstProduct = new ObservableCollection<BusinessModel.Product>(MtdGetAll().ToResult<IList<Product>>());
                    IProductView.ReloadData("LstProduct");
                    IProductView.CompletedHandler("EvtDelete");
                    result = true;
                }
            }
            return result;
        }
        //----------------------------------------
        public bool MtdSave(params object[] pParams)
        {
            // Check validate.
            if (DicError.Count > 0)
            {
                IProductView.ErrorHandler("EvtSave", DicError);
                return false;
            }
            bool result = false;
            if (IProductView.BeforeHandler("EvtSave"))
            {
                if (Product.Id == default(int))
                {
                    Product.CreatedBy = ControllerConfig.Default.UserName;
                    Product.CreatedDate = DateTime.Now;
                }
                Product.ModifiedBy = ControllerConfig.Default.UserName;
                Product.ModifiedDate = DateTime.Now;

                EntityKey oEntityKey = new EntityKey(BaseProvider.QualifyName + "." + ProductPro.EntityName, "Id", Product.Id);
                ResultModel oResultModel = ProductPro.Save(Product, oEntityKey);
                if (oResultModel.HasError)
                {
                    IProductView.ErrorHandler("EvtSave", oResultModel);
                }
                else
                {
                    LstProduct = new ObservableCollection<BusinessModel.Product>(MtdGetAll().ToResult<IList<Product>>());
                    IProductView.ReloadData("LstProduct");
                    IProductView.CompletedHandler("EvtSave", oResultModel.Result);
                    result = true;
                }
            }
            return result;
        }
        //----------------------------------------
        public bool MtdGetAllChilds(Action<object> pAction, params object[] pParams)
        {
            bool result = false;
            int? iParentId = null;
            if (pParams.Count() == 1)
            {
                iParentId = int.Parse(pParams[0].ToString());
            }
            IList<ProductType> lstPro = ProductTypePro.GetAllChilds(iParentId).ToResult<IList<ProductType>>();
            pAction(lstPro);
            return result;
        }
        //----------------------------------------
        public bool MtdGetAllByTypeId(params object[] pParams)
        {
            bool result = false;
            int iTypeId = 0;
            if (pParams.Count() == 1)
            {
                iTypeId = int.Parse(pParams[0].ToString());
            }
            LstProduct = ProductPro.GetAllByTypeId(iTypeId).ToResult<IList<Product>>();
            IProductView.ReloadData("LstProduct");
            return result;
        }
        //----------------------------------------
        public bool MtdReloadLstProductType(params object[] pParams)
        {
            bool result = false;
            _LstProductType = null;
            IProductView.ReloadData("LstProductType");
            return result;
        }
        //----------------------------------------
        public bool MtdReloadLstUnit(params object[] pParams)
        {
            bool result = false;
            _LstUnit = null;
            IProductView.ReloadData("LstUnit");
            return result;
        }
        #endregion Public View Handlers

        #region IDataErrorInfo Members
        private string _Error;
        public string Error
        {
            get
            {
                return _Error;
            }
        }
        public string this[string columnName]
        {
            get
            {
                string error = string.Empty;
                if (DicError.Keys.Contains(columnName))
                    DicError.Remove(columnName);
                switch (columnName)
                {
                    case "ProductTypeId":
                        if (!ProductTypeId.HasValue || ProductTypeId.Value == default(int))
                        {
                            error = "Mã hàng hóa không được rỗng.";
                        }
                        break;
                    case "ProductCode":
                        if (string.IsNullOrWhiteSpace(ProductCode))
                        {
                            error = "Mã hàng hóa không được rỗng.";
                        }
                        break;
                    case "ProductName":
                        if (string.IsNullOrWhiteSpace(ProductName))
                        {
                            error = "Tên hàng hóa không được rỗng.";
                        }
                        break;
                    case "UnitId":
                        if (UnitId == default(int))
                        {
                            error = "Chưa chọn đơn vị tính.";
                        }
                        break;
                }
                _Error = error;
                if (!string.IsNullOrWhiteSpace(error))
                {
                    DicError.Add(columnName, error);
                }
                IProductView.ValidationHandler(columnName, error);
                return error;
            }
        }
        #endregion
    }
}
